﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using NopSolutions.NopCommerce.BusinessLogic;
using NopSolutions.NopCommerce.BusinessLogic.Infrastructure;
using NopSolutions.NopCommerce.BusinessLogic.Model;
using NopSolutions.NopCommerce.BusinessLogic.SEO;
using NopSolutions.NopCommerce.BusinessLogic.Services;
using NopSolutions.NopCommerce.BusinessLogic.Utils;
using NopSolutions.NopCommerce.Common.Utils;

namespace NopSolutions.NopCommerce.Web.Templates.Products
{
    public partial class BundleTemplate : BaseNopFrontendUserControl
    {
        private readonly IProductService _productService;
        private readonly IPictureService _pictureService;
        private readonly ICurrencyService _currencyService;
        private readonly IDownloadService _downloadService;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly ISettingService _settingService;
        private readonly ILogService _logService;

        private Product _product;
        private IList<Bundle> _bundles;

        public BundleTemplate() {
            _productService = IoC.Resolve<IProductService>();
            _pictureService = IoC.Resolve<IPictureService>();
            _currencyService = IoC.Resolve<ICurrencyService>();
            _downloadService = IoC.Resolve<IDownloadService>();
            _shoppingCartService = IoC.Resolve<IShoppingCartService>();
            _settingService = IoC.Resolve<ISettingService>();
            _logService = IoC.Resolve<ILogService>();
        }

        protected override void OnInit(EventArgs e) {
            base.OnInit(e);

            Load += new EventHandler(Bundle_Load);
            rptBundle.ItemDataBound += new RepeaterItemEventHandler(rptBundle_ItemDataBound);
        }

        void Bundle_Load(object sender, EventArgs e) {
            if (!IsPostBack) {
                BindData();
            }
        }

        #region Properties

        public new IProductService ProductService { get { return _productService; } }
        public new IPictureService PictureService { get { return _pictureService; } }
        public new ICurrencyService CurrencyService { get { return _currencyService; } }
        public new IDownloadService DownloadService { get { return _downloadService; } }
        public new IShoppingCartService ShoppingCartService { get { return _shoppingCartService; } }
        public ISettingService SettingService { get { return _settingService; } }
        public new ILogService LogService { get { return _logService; } }

        public int ProductId {
            get {
                return CommonHelper.RouteStringInt("productId");
            }
        }

        public Product Product {
            get {
                if (_product == null)
                    _product = _productService.GetProductById(ProductId);
                return _product;
            }
        }

        public ProductVariant ProductVariant {
            get {
                if (Product != null && Product.ProductVariants.Count > 0) {
                    return Product.ProductVariants[0];
                }
                return null;
            }
        }

        public IList<Bundle> Bundles {
            get {
                if (_bundles == null) {
                    _bundles = ProductService.GetAllBundlesByProductId(ProductId);
                }

                return _bundles;
            }
        }

        #endregion

        private void BindData() {
            if (Product == null || Product.ProductVariants.Count == 0) {
                Response.Redirect(CommonHelper.GetStoreLocation());
            }

            litProductName.Text = Server.HtmlEncode(Product.LocalizedName);
            litShortDescription.Text = Server.HtmlEncode(Product.LocalizedShortDescription);
            lFullDescription.Text = Product.LocalizedFullDescription;

            //pictures
            var pictures = PictureService.GetPicturesByProductId(Product.ProductId);
            if (pictures.Count > 1) {
                defaultImage.ImageUrl = PictureService.GetPictureUrl(pictures[0], SettingService.GetSettingValueInteger("Media.Product.DetailImageSize", 300));
                defaultImage.ToolTip = String.Format(GetLocaleResourceString("Media.Product.ImageAlternateTextFormat"), Product.LocalizedName);
                defaultImage.AlternateText = String.Format(GetLocaleResourceString("Media.Product.ImageAlternateTextFormat"), Product.LocalizedName);
                rptProductPictures.DataSource = pictures;
                rptProductPictures.DataBind();
            }
            else if (pictures.Count == 1) {
                defaultImage.ImageUrl = PictureService.GetPictureUrl(pictures[0], SettingService.GetSettingValueInteger("Media.Product.DetailImageSize", 300));
                defaultImage.ToolTip = String.Format(GetLocaleResourceString("Media.Product.ImageAlternateTextFormat"), Product.LocalizedName);
                defaultImage.AlternateText = String.Format(GetLocaleResourceString("Media.Product.ImageAlternateTextFormat"), Product.LocalizedName);
                rptProductPictures.Visible = false;
            }
            else {
                defaultImage.ImageUrl = PictureService.GetDefaultPictureUrl(SettingService.GetSettingValueInteger("Media.Product.DetailImageSize", 300));
                defaultImage.ToolTip = String.Format(GetLocaleResourceString("Media.Product.ImageAlternateTextFormat"), Product.LocalizedName);
                defaultImage.AlternateText = String.Format(GetLocaleResourceString("Media.Product.ImageAlternateTextFormat"), Product.LocalizedName);
                rptProductPictures.Visible = false;
            }
            if (SettingService.GetSettingValueBoolean("Media.Product.DefaultPictureZoomEnabled", false)) {
                var picture = Product.DefaultPicture;
                if (picture != null) {
                    lnkMainLightbox.Attributes["href"] = PictureService.GetPictureUrl(picture);
                    lnkMainLightbox.Attributes["rel"] = "lightbox";
                }
            }

            btnAddToWishlist.Visible = SettingService.GetSettingValueBoolean("Common.EnableWishlist");

            //sku
            if (SettingService.GetSettingValueBoolean("Display.Products.ShowSKU") && !String.IsNullOrEmpty(ProductVariant.SKU)) {
                phSKU.Visible = true;
                lSKU.Text = Server.HtmlEncode(ProductVariant.SKU);
            }
            else {
                phSKU.Visible = false;
            }

            //manufacturer part number
            if (SettingService.GetSettingValueBoolean("Display.Products.ShowManufacturerPartNumber") && !String.IsNullOrEmpty(ProductVariant.ManufacturerPartNumber)) {
                phManufacturerPartNumber.Visible = true;
                lManufacturerPartNumber.Text = Server.HtmlEncode(ProductVariant.ManufacturerPartNumber);
            }
            else {
                phManufacturerPartNumber.Visible = false;
            }

            ctrlTierPrices.ProductVariantId = ProductVariant.ProductVariantId;
            ctrlProductAttributes.ProductVariantId = ProductVariant.ProductVariantId;
            ctrlGiftCardAttributes.ProductVariantId = ProductVariant.ProductVariantId;
            ctrlProductPrice.ProductVariantId = ProductVariant.ProductVariantId;

            //stock
            string stockMessage = ProductVariant.FormatStockMessage();
            if (!String.IsNullOrEmpty(stockMessage)) {
                if (ProductVariant.StockQuantity > 0) {
                    pnlStockAvailablity.CssClass = "alert-box success";
                }
                else {
                    pnlStockAvailablity.CssClass = "alert-box error";
                }
                lblStockAvailablity.Text = stockMessage;
            }
            else {
                pnlStockAvailablity.Visible = false;
            }

            //price entered by a customer
            if (ProductVariant.CustomerEntersPrice) {
                decimal minimumCustomerEnteredPrice = CurrencyService.ConvertCurrency(ProductVariant.MinimumCustomerEnteredPrice, CurrencyService.PrimaryStoreCurrency, NopContext.Current.WorkingCurrency);
                decimal maximumCustomerEnteredPrice = CurrencyService.ConvertCurrency(ProductVariant.MaximumCustomerEnteredPrice, CurrencyService.PrimaryStoreCurrency, NopContext.Current.WorkingCurrency);
                txtCustomerEnteredPrice.Visible = true;
                txtCustomerEnteredPrice.ValidationGroup = string.Format("ProductVariant{0}", ProductVariant.ProductVariantId);
                txtCustomerEnteredPrice.Value = minimumCustomerEnteredPrice;
                txtCustomerEnteredPrice.MinimumValue = minimumCustomerEnteredPrice.ToString();
                txtCustomerEnteredPrice.MaximumValue = maximumCustomerEnteredPrice.ToString();
                txtCustomerEnteredPrice.RangeErrorMessage = string.Format(GetLocaleResourceString("Products.CustomerEnteredPrice.Range"),
                    PriceHelper.FormatPrice(minimumCustomerEnteredPrice, false, false),
                        PriceHelper.FormatPrice(maximumCustomerEnteredPrice, false, false));
            }
            else {
                txtCustomerEnteredPrice.Visible = false;
            }

            //buttons
            if (!ProductVariant.DisableBuyButton) {
                txtQuantity.ValidationGroup = string.Format("ProductVariant{0}", ProductVariant.ProductVariantId);
                btnAddToCart.ValidationGroup = string.Format("ProductVariant{0}", ProductVariant.ProductVariantId);
                btnAddToWishlist.ValidationGroup = string.Format("ProductVariant{0}", ProductVariant.ProductVariantId);

                txtQuantity.Value = ProductVariant.OrderMinimumQuantity;
            }
            else {
                txtQuantity.Visible = false;
                btnAddToCart.Visible = false;
                btnAddToWishlist.Visible = false;
            }

            //samle downlaods
            if (pnlDownloadSample != null && hlDownloadSample != null) {
                if (ProductVariant.IsDownload && ProductVariant.HasSampleDownload) {
                    pnlDownloadSample.Visible = true;
                    hlDownloadSample.NavigateUrl = DownloadService.GetSampleDownloadUrl(ProductVariant);
                }
                else {
                    pnlDownloadSample.Visible = false;
                }
            }

            // bundles
            rptBundle.DataSource = Bundles;
            rptBundle.DataBind();

            if (SettingService.GetSettingValueBoolean("Product.Bundle.ShowSave")) {
                // get total bundle variants price
                decimal bundlePrice = 0;
                Bundles.ToList().ForEach(b => {
                    bundlePrice += b.ProductVariant.Price;
                });
                decimal bundleSave = bundlePrice - ProductVariant.Price;

                litBundleSave.Visible = true;
                litBundleSave.Text = string.Format(GetLocaleResourceString("Product.Bundle.Save"), PriceHelper.FormatPrice(bundleSave));
            }
            else {
                litBundleSave.Visible = false;
            }

            //final check - hide prices for non-registered customers
            if (!SettingService.GetSettingValueBoolean("Common.HidePricesForNonRegistered") ||
                    (NopContext.Current.User != null &&
                    !NopContext.Current.User.IsGuest)) {
                //
            }
            else {
                txtCustomerEnteredPrice.Visible = false;
                txtQuantity.Visible = false;
                btnAddToCart.Visible = false;
                btnAddToWishlist.Visible = false;
            }
        }

        protected void OnCommand(object source, CommandEventArgs e) {
            if (ProductVariant == null) {
                return;
            }

            string attributes = ctrlProductAttributes.SelectedAttributes;
            decimal customerEnteredPrice = txtCustomerEnteredPrice.Value;
            decimal customerEnteredPriceConverted = CurrencyService.ConvertCurrency(customerEnteredPrice, NopContext.Current.WorkingCurrency, CurrencyService.PrimaryStoreCurrency);
            int quantity = txtQuantity.Value;

            //gift cards
            if (ProductVariant.IsGiftCard) {
                string recipientName = ctrlGiftCardAttributes.RecipientName;
                string recipientEmail = ctrlGiftCardAttributes.RecipientEmail;
                string senderName = ctrlGiftCardAttributes.SenderName;
                string senderEmail = ctrlGiftCardAttributes.SenderEmail;
                string giftCardMessage = ctrlGiftCardAttributes.GiftCardMessage;

                attributes = ProductAttributeHelper.AddGiftCardAttribute(attributes, recipientName, recipientEmail, senderName, senderEmail, giftCardMessage);
            }

            try {
                if (e.CommandName == "AddToCart") {
                    var addToCartWarnings = ShoppingCartService.AddToCart(ShoppingCartTypeEnum.ShoppingCart, ProductVariant.ProductVariantId, attributes, customerEnteredPriceConverted, quantity);
                    if (addToCartWarnings.Count == 0) {
                        if (this.SettingManager.GetSettingValueBoolean("Display.Products.DisplayCartAfterAddingProduct")) {
                            //redirect to shopping cart page
                            Response.Redirect(SEOHelper.GetShoppingCartUrl());
                        }
                        else {
                            //display notification message
                            this.DisplayAlertMessage(GetLocaleResourceString("Products.ProductHasBeenAddedToTheCart"));
                        }
                    }
                    else {
                        var addToCartWarningsSb = new StringBuilder();
                        addToCartWarningsSb.Append("<p>" + GetLocaleResourceString("Products.RequiredAttributes") + "</p>");
                        addToCartWarningsSb.Append("<ul>");
                        for (int i = 0; i < addToCartWarnings.Count; i++) {
                            addToCartWarningsSb.Append("<li>" + Server.HtmlEncode(addToCartWarnings[i]) + "</li>");
                        }
                        addToCartWarningsSb.Append("</ul>");
                        string errorFull = addToCartWarningsSb.ToString();
                        pnlAlert.Visible = true;
                        lblError.Text = errorFull;
                        if (SettingService.GetSettingValueBoolean("Common.ShowAlertForProductAttributes")) {
                            this.DisplayAlertMessage(errorFull);
                        }
                    }
                }

                if (e.CommandName == "AddToWishlist") {
                    var addToCartWarnings = ShoppingCartService.AddToCart(ShoppingCartTypeEnum.Wishlist, ProductVariant.ProductVariantId, attributes, customerEnteredPriceConverted, quantity);
                    if (addToCartWarnings.Count == 0) {
                        Response.Redirect(SEOHelper.GetWishlistUrl());
                    }
                    else {
                        var addToCartWarningsSb = new StringBuilder();
                        addToCartWarningsSb.Append("<p>" + GetLocaleResourceString("Products.RequiredAttributes") + "</p>");
                        addToCartWarningsSb.Append("<ul>");
                        for (int i = 0; i < addToCartWarnings.Count; i++) {
                            addToCartWarningsSb.Append("<li>" + Server.HtmlEncode(addToCartWarnings[i]) + "</li>");
                        }
                        addToCartWarningsSb.Append("</ul>");
                        string errorFull = addToCartWarningsSb.ToString();
                        pnlAlert.Visible = true;
                        lblError.Text = errorFull;
                        if (SettingService.GetSettingValueBoolean("Common.ShowAlertForProductAttributes")) {
                            this.DisplayAlertMessage(errorFull);
                        }
                    }
                }
            }
            catch (Exception exc) {
                LogService.InsertLog(LogTypeEnum.CustomerError, exc.Message, exc);
                pnlAlert.Visible = true;
                lblError.Text = Server.HtmlEncode(exc.Message);
            }
        }

        void rptBundle_ItemDataBound(object sender, RepeaterItemEventArgs e) {
            if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) {
                var bundle = e.Item.DataItem as Bundle;
                if (bundle != null) {
                    var hlProductName = e.Item.FindControl("hlProductName") as HyperLink;
                    hlProductName.Text = bundle.ProductVariant.Product.LocalizedName;
                    hlProductName.NavigateUrl = SEOHelper.GetProductUrl(bundle.ProductVariant.Product);

                    var hlProductImage = e.Item.FindControl("hlProductImage") as HyperLink;
                    hlProductImage.ImageUrl = _pictureService.GetPictureUrl(bundle.ProductVariant.Product.DefaultPicture.PictureId, _settingService.GetSettingValueInteger("Media.Category.ThumbnailImageSize", 125), true);
                    hlProductImage.Width = Unit.Pixel(125);
                    hlProductImage.Height = Unit.Pixel(125);
                    hlProductImage.NavigateUrl = hlProductName.NavigateUrl;
                    hlProductImage.ToolTip = String.Format(GetLocaleResourceString("Media.Category.ImageLinkTitleFormat"), bundle.ProductVariant.Product.LocalizedName);
                    hlProductImage.Text = String.Format(GetLocaleResourceString("Media.Category.ImageAlternateTextFormat"), bundle.ProductVariant.Product.LocalizedName);
                }
            }
        }
    }
}